package myJs.common.loadSample

import myJs.CpLayer
import myJs.Implicits._
import myJs.api.Api
import myJs.myPkg.jquery.$
import myJs.myPkg.{MyFetch, SwalOptions, layer, swal}
import myJs.tool.Tool
import org.scalajs.dom.{File, FormData, html}
import slinky.core.FunctionalComponent
import slinky.core.annotations.react
import slinky.core.facade.Hooks.{useEffect, useState}
import slinky.core.facade.React
import slinky.web.html._

import scala.scalajs.js
import scala.scalajs.js.Dynamic.{global => g}
import scala.scalajs.js.JSConverters._
import org.scalajs.macrotaskexecutor.MacrotaskExecutor.Implicits._
import com.softwaremill.quicklens._
import myJs.common.{CommentCp, PureInputCp, PureRSelectCp, TestInfoCp}
import myJs.cps.{ImageSelectCp, PureAsyncRSelectInlineCp, PureDatePickerCp, PureDateTimePickerCp, PureSelectCp, Style}
import myJs.myPkg.reactHookForm.{ReactHookForm, RegisterOptions, UseFormOptions, ValidationValueMessage}
import shared.pojo.FreezerSet.FreezerSetData
import shared.pojo.Sample.{CommentData, SampleInfo, TestData}

import scala.collection.immutable.SeqMap
import scala.scalajs.js.{Date, JSON}
import upickle.default._

import scala.util.{Failure, Success}

/**
 * Created by yz on 21/1/2022
 */
@react object Cp {

  val curPage = LoadSample
  type Props = Unit

  val component = FunctionalComponent[Props] { props =>

    val dateStr = Tool.formatDate(new Date())
    val initSampleInfo = SampleInfo(date = dateStr)
    val (sampleInfo, setSampleInfo) = useState(initSampleInfo)
    val (files, setFiles) = useState(List[File]())
    val (rowNumberMap, setRowNumberMap) = useState(SeqMap("" -> "无"))
    val (colNumberMap, setColNumberMap) = useState(SeqMap("" -> "无"))

    val useForm = ReactHookForm.useForm(UseFormOptions(mode = "onChange"))

    object FTool {

      def refreshRowColMap = {
        val request = FreezerSetData(freezerNumber = sampleInfo.freezerNumber,
          freezerLayerNumber = sampleInfo.freezerLayerNumber)
        Api.freezerSet.get(request).map { op =>
          val (curRowNumberMap, curColNumberMap) = if (request.freezerNumber.nonBlank && request.freezerLayerNumber.nonBlank) {
            val curFreezerSet = op.getOrElse(FreezerSetData())
            val rowNumberMap = SeqMap("" -> "无") ++ (1 to curFreezerSet.totalRowNumber.toInt).map(_.toString).toList.optionMap
            val colNumberMap = SeqMap("" -> "无") ++ (1 to curFreezerSet.totalColNumber.toInt).map(_.toString).toList.optionMap
            (rowNumberMap, colNumberMap)
          } else {
            (SeqMap("" -> "无"), SeqMap("" -> "无"))
          }
          setRowNumberMap(curRowNumberMap)
          setColNumberMap(curColNumberMap)
        }.onComplete {
          case Success(value) =>
          case Failure(e) =>
            e.printStackTrace()
        }
      }

      def filesChange = (vs: List[File]) => {
        setFiles(vs)
      }

      def add = () => {
        val index = layer.alert(Tool.myElement, Tool.layerOptions)
        val formData = new FormData()
        files.zipWithIndex.foreach { case (file, curI) =>
          formData.append(s"labFiles", file)
        }
        formData.append("sampleInfo", write(sampleInfo))
        Api.sample.add(formData) { xhr =>
          layer.close(index)
          swal(SwalOptions(title = "成功", text = "录入成功!", `type` = "success"))
        }
        ()
      }

      val removeImg = (curI: Int) => {
        val curUris = sampleInfo.images.removedByI(curI)
        val curSampleInfo = sampleInfo.modify(_.images).setTo(curUris)
        setSampleInfo(curSampleInfo)
      }

      val imagesAdd = (curUris: List[String]) => {
        val curImages = sampleInfo.images ::: curUris
        val curSampleInfo = sampleInfo.modify(_.images).setTo(curImages)
        setSampleInfo(curSampleInfo)
      }

      def idChange = (v: String) => {
        val curSampleInfo = sampleInfo.modify(_.id).setTo(v)
        setSampleInfo(curSampleInfo)
      }

      def dateChange = (v: String) => {
        val curSampleInfo = sampleInfo.modify(_.date).setTo(v)
        setSampleInfo(curSampleInfo)
      }

      def addressChange = (v: String) => {
        val curSampleInfo = sampleInfo.modify(_.address).setTo(v)
        setSampleInfo(curSampleInfo)
      }

      def elevationChange = (v: String) => {
        val curSampleInfo = sampleInfo.modify(_.elevation).setTo(v)
        setSampleInfo(curSampleInfo)
      }

      def sampleLineNumberChange = (v: String) => {
        val curSampleInfo = sampleInfo.modify(_.sampleLineNumber).setTo(v)
        setSampleInfo(curSampleInfo)
      }

      def longitudeChange = (v: String) => {
        val curSampleInfo = sampleInfo.modify(_.longitude).setTo(v)
        setSampleInfo(curSampleInfo)
      }

      def latitudeChange = (v: String) => {
        val curSampleInfo = sampleInfo.modify(_.latitude).setTo(v)
        setSampleInfo(curSampleInfo)
      }

      def sampleTypeChange = (v: String) => {
        val curSampleInfo = sampleInfo.modify(_.sampleType).setTo(v)
        setSampleInfo(curSampleInfo)
      }

      def freshnessChange = (v: String) => {
        val curSampleInfo = sampleInfo.modify(_.freshness).setTo(v)
        setSampleInfo(curSampleInfo)
      }

      def gathererChange = (v: String) => {
        val curSampleInfo = sampleInfo.modify(_.gatherer).setTo(v)
        setSampleInfo(curSampleInfo)
      }

      def weatherChange = (v: String) => {
        val curSampleInfo = sampleInfo.modify(_.weather).setTo(v)
        setSampleInfo(curSampleInfo)
      }

      def freezerNumberChange = (v: String) => {
        setSampleInfo(sampleInfo.modify(_.freezerNumber).setTo(v))
      }

      def freezerLayerNumberChange = (v: String) => {
        setSampleInfo(sampleInfo.modify(_.freezerLayerNumber).setTo(v))
      }

      def rowNumberChange = (v: String) => {
        setSampleInfo(sampleInfo.modify(_.rowNumber).setTo(v))
      }

      def colNumberChange = (v: String) => {
        setSampleInfo(sampleInfo.modify(_.colNumber).setTo(v))
      }

      def removeServerImg = (curI: Int) => {
        val curUris = sampleInfo.serverImages.removedByI(curI)
        val curSampleInfo = sampleInfo.modify(_.serverImages).setTo(curUris)
        setSampleInfo(curSampleInfo)
      }

      def sampleInfoChange = (v: SampleInfo) => {
        setSampleInfo(v)
      }

    }

    useEffect(() => {
      FTool.refreshRowColMap
    }, List(sampleInfo.freezerNumber, sampleInfo.freezerLayerNumber)
    )

    CpLayer(title = curPage.titleStr)(
      div(className := "page-content",
        div(className := "row-fluid",
          div(className := "row",
            div(className := "col-md-12 col-sm-12",
              div(className := "portlet light",
                div(className := "portlet-title",
                  div(className := "caption", s"${curPage.titleStr}")
                ),
                div(className := "portlet-body",

                  form(className := "form-horizontal", id := "form", onSubmit := {
                    useForm.handleSubmit((data: js.Dictionary[js.Any]) => {
                      println(JSON.stringify(data))
                      FTool.add()
                    })
                  },
                    h4("基本信息"),

                    {
                      PureAsyncRSelectInlineCp(useForm = useForm, onChange = FTool.idChange,
                        name = "id", value = sampleInfo.id,
                        registerOptions = {
                          val info = "样本编号"
                          RegisterOptions(
                            required = ValidationValueMessage(value = true, message = s"${info}不能为空！"),
                          )
                        }
                      )
                    },

                    div(className := "form-group",
                      label(className := "control-label col-sm-2", "日期:"),
                      div(className := "col-sm-4",
                        PureDatePickerCp(placeHolder = s"", name = "endTime", value = sampleInfo.date,
                          onChangeF = FTool.dateChange)
                      ),
                      label(className := "control-label col-sm-2", "地点:"),
                      div(className := "col-sm-4",
                        PureInputCp(useForm = useForm, name = "address", value = sampleInfo.address,
                          onChange = FTool.addressChange,
                        )
                      )
                    ),

                    div(className := "form-group",
                      label(className := "control-label col-sm-2", "海拔:"),
                      div(className := "col-sm-4",
                        PureInputCp(useForm = useForm, name = "elevation", value = sampleInfo.elevation,
                          onChange = FTool.elevationChange,
                        )
                      ),
                      label(className := "control-label col-sm-2", "样线号:"),
                      div(className := "col-sm-4",
                        PureInputCp(useForm = useForm, name = "sampleLineNumber", value = sampleInfo.sampleLineNumber,
                          onChange = FTool.sampleLineNumberChange,
                        )
                      ),
                    ),

                    div(className := "form-group",
                      label(className := "control-label col-sm-2", "经度:"),
                      div(className := "col-sm-4",
                        PureInputCp(useForm = useForm, name = "longitude", value = sampleInfo.longitude,
                          onChange = FTool.longitudeChange,
                        )
                      ),
                      label(className := "control-label col-sm-2", "纬度:"),
                      div(className := "col-sm-4",
                        PureInputCp(useForm = useForm, name = "latitude", value = sampleInfo.latitude,
                          onChange = FTool.latitudeChange,
                        )
                      ),
                    ),

                    div(className := "form-group",
                      label(className := "control-label col-sm-2", "样品类型:"),
                      div(className := "col-sm-4",
                        PureInputCp(useForm = useForm, name = "sampleType", value = sampleInfo.sampleType,
                          onChange = FTool.sampleTypeChange,
                        )
                      )
                    ),

                    div(className := "form-group",
                      label(className := "control-label col-sm-2", "样品照片:"),
                      div(className := "col-sm-10",
                        ImageSelectCp(serverImages = sampleInfo.serverImages, images = sampleInfo.images,
                          removeImg = FTool.removeImg, imagesAdd = FTool.imagesAdd, id = sampleInfo.id,
                          removeServerImg = FTool.removeServerImg)
                      )
                    ),

                    div(className := "form-group",
                      label(className := "control-label col-sm-2", "新鲜程度:"),
                      div(className := "col-sm-4",
                        PureInputCp(useForm = useForm, name = "freshness", value = sampleInfo.freshness,
                          onChange = FTool.freshnessChange,
                        )
                      ),
                      label(className := "control-label col-sm-2", "采集人:"),
                      div(className := "col-sm-4",
                        PureInputCp(useForm = useForm, name = "gatherer", value = sampleInfo.gatherer,
                          onChange = FTool.gathererChange,
                        )
                      )
                    ),

                    div(className := "form-group",
                      label(className := "control-label col-sm-2", "天气:"),
                      div(className := "col-sm-4",
                        PureInputCp(useForm = useForm, name = "weather", value = sampleInfo.weather,
                          onChange = FTool.weatherChange
                        )
                      ),
                    ),

                    h4("冰箱信息"),

                    div(className := "form-group",
                      label(className := "control-label col-sm-2", "冰箱编号:"),
                      div(className := "col-sm-4",
                        PureRSelectCp(useForm = useForm, name = "freezerNumber", value = sampleInfo.freezerNumber,
                          onChange = FTool.freezerNumberChange, optionMap = Tool.freezerNumberMap
                        )
                      ),
                      label(className := "control-label col-sm-2", "层数:"),
                      div(className := "col-sm-4",
                        PureRSelectCp(useForm = useForm, name = "freezerLayerNumber", value = sampleInfo.freezerLayerNumber,
                          onChange = FTool.freezerLayerNumberChange, optionMap = Tool.freezerLayerNumberMap
                        )
                      )
                    ),

                    div(className := "form-group",
                      label(className := "control-label col-sm-2", "行数:"),
                      div(className := "col-sm-4",
                        PureRSelectCp(useForm = useForm, name = "rowNumber", value = sampleInfo.rowNumber,
                          onChange = FTool.rowNumberChange, optionMap = rowNumberMap
                        )
                      ),
                      label(className := "control-label col-sm-2", "列数:"),
                      div(className := "col-sm-4",
                        PureRSelectCp(useForm = useForm, name = "colNumber", value = sampleInfo.colNumber,
                          onChange = FTool.colNumberChange, optionMap = colNumberMap
                        )
                      )
                    ),

                    CommentCp(useForm = useForm, sampleInfo = sampleInfo, sampleInfoChange = FTool.sampleInfoChange),

                    LabCp(useForm = useForm, sampleInfo = sampleInfo, sampleInfoChange = FTool.sampleInfoChange,
                      files = files, filesChange = FTool.filesChange),

                    h4("测试信息"),

                    TestInfoCp(useForm = useForm, sampleInfo = sampleInfo, sampleInfoChange = FTool.sampleInfoChange),

                    div(className := "form-group",
                      div(className := "actions col-sm-offset-2 col-sm-2",
                        button(`type` := "submit", className := "btn btn-primary myAddShow",
                          s" 录入",
                        ),
                      )
                    ),

                  ),

                ),
              )
            )
          )
        )
      )
    )

  }


}
